class AuthD::Request
	IPC::JSON.message AskPasswordRecovery, 3 do
		property login      : String? = nil
		property email      : String? = nil

		def initialize(@login = nil, @email = nil)
		end

		def to_s(io : IO)
			super io
			io << " (login: #{@login})"
		end

		def handle(authd : AuthD::Service, fd : Int32)
			if @login.nil? && @email.nil?
				return Response::ErrorUserNotFound.new
			end

			user = if l = @login
				authd.user? l
			elsif mail = @email
				authd.users_per_email.get? Base64.encode(mail).chomp
			else
				nil
			end

			# This is a way for an attacker to know what are the valid logins.
			# Not sure I care enough to fix this.
			return Response::ErrorUserNotFound.new if user.nil?

			# Create a new random key for password renewal.
			user.password_renew_key = UUID.random.to_s
			authd.users_per_uid.update user.uid.to_s, user

			# TODO: this is debug information. Should be removed once tested.
			# Once the user is created and stored, we try to contact him
			if authd.configuration.print_password_recovery_parameters
				pp! user.login,
					user.contact.email.not_nil!,
					user.password_renew_key.not_nil!
			end

			u_login = user.login
			u_email = user.contact.email.not_nil!
			u_token = user.password_renew_key.not_nil!

			send_recovery_token authd, u_login, u_email, u_token

			Response::PasswordRecoverySent.new
		end
	end
	AuthD.requests << AskPasswordRecovery

	IPC::JSON.message PasswordRecovery, 4 do
		property user               : UserID
		property password_renew_key : String
		property new_password       : String

		def initialize(@user, @password_renew_key, @new_password)
		end

		def to_s(io : IO)
			super io
			io << " (user: #{@user}, password_renew_key: #{@password_renew_key})"
		end

		def handle(authd : AuthD::Service, fd : Int32)
			user = authd.user? @user
			# This is a way for an attacker to know what are the valid logins.
			# Not sure I care enough to fix this.
			return Response::ErrorUserNotFound.new if user.nil?

			if user.password_renew_key == @password_renew_key
				user.password_hash = authd.hash_password @new_password
			else
				return Response::ErrorInvalidRenewKey.new
			end

			user.password_renew_key = nil

			authd.users_per_uid.update user.uid.to_s, user

			Response::PasswordRecovered.new
		end
	end
	AuthD.requests << PasswordRecovery
end
